www.gusucode.com > VC++ 分形图像编辑器源码源码程序 > VC++ 分形图像编辑器源码源码程序\code\ColorPopup.cpp

    //贵州省安顺市第二高级中学 高二一班 蒋伟	
//2002.7.1
//请勿修改版权信息 谢谢
//Neil
// Download by http://www.NewXing.com

#include "stdafx.h"
#include <math.h>

#include "ColorPopup.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define DEFAULT_BOX_VALUE -3
#define CUSTOM_BOX_VALUE  -2
#define INVALID_COLOUR    -1

#define MAX_COLOURS      100

#define MAX_OFFSET  5          // X direction offset
#define MAX_BOTTOM  15         // Y direction offset and to the bottom 
#define MAX_TEXTRECT -5        // Width of the default text rect and the onwer text rect    

ColorTableEntry CColorPopup::m_crColors[] = 
{
    { RGB(0x01, 0x00, 0x00),    _T("黑色")              },
    { RGB(0xA5, 0x2A, 0x00),    _T("褐色")              },
    { RGB(0x00, 0x40, 0x40),    _T("橄榄绿")            },
    { RGB(0x00, 0x55, 0x00),    _T("深绿")              },
    { RGB(0x00, 0x00, 0x5E),    _T("深灰蓝")            },
    { RGB(0x00, 0x00, 0x8B),    _T("深蓝")              },
    { RGB(0x4B, 0x00, 0x82),    _T("靛蓝")              },
    { RGB(0x33, 0x33, 0x33),    _T("深灰-80%")          },

    { RGB(0x8B, 0x00, 0x00),    _T("深红")	            },
    { RGB(0xFF, 0x68, 0x20),    _T("桔黄")              },
    { RGB(0x8B, 0x8B, 0x00),    _T("深黄")              },
    { RGB(0x00, 0x93, 0x00),    _T("绿色")              },
    { RGB(0x38, 0x8E, 0x8E),    _T("青色")              },
    { RGB(0x00, 0x00, 0xFF),    _T("蓝色")              },
    { RGB(0x7B, 0x7B, 0xC0),    _T("蓝灰")              },
    { RGB(0x7F, 0x7F, 0x7F),    _T("灰色-50%")          },

    { RGB(0xFF, 0x00, 0x00),    _T("红色")              },
    { RGB(0xFF, 0xAD, 0x5B),    _T("浅桔色")            },
    { RGB(0x32, 0xCD, 0x32),    _T("酸桔色")            }, 
    { RGB(0x3C, 0xB3, 0x71),    _T("海绿")              },
    { RGB(0x7F, 0xFF, 0xD4),    _T("宝石蓝")            },
    { RGB(0x7D, 0x9E, 0xC0),    _T("浅蓝")              },
    { RGB(0x80, 0x00, 0x80),    _T("紫色")              },
    { RGB(0x99, 0x99, 0x99),    _T("灰色-40%")          },

    { RGB(0xFF, 0xC0, 0xCB),    _T("粉红")              },
    { RGB(0xFF, 0xD7, 0x00),    _T("金色")              },
    { RGB(0xFF, 0xFF, 0x00),    _T("黄色")              },    
    { RGB(0x00, 0xFF, 0x00),    _T("鲜绿")              },
    { RGB(0x40, 0xE0, 0xD0),    _T("青绿")              },
    { RGB(0xC0, 0xFF, 0xFF),    _T("天蓝")              },
    { RGB(0x48, 0x00, 0x48),    _T("梅红")              },
    { RGB(0xBF, 0xBF, 0xBF),    _T("灰色-25%")          },

    { RGB(0xFF, 0xE4, 0xE1),    _T("玫瑰红")            },
    { RGB(0xD2, 0xB4, 0x8C),    _T("棕色")              },
    { RGB(0xFF, 0xFF, 0xE0),    _T("浅黄")              },
    { RGB(0x98, 0xFB, 0x98),    _T("浅绿 ")             },
    { RGB(0xAF, 0xEE, 0xEE),    _T("浅青绿")            },
    { RGB(0x68, 0x83, 0x8B),    _T("淡蓝")              },
    { RGB(0xE6, 0xE6, 0xFA),    _T("紫色")              },
    { RGB(0xFF, 0xFF, 0xFF),    _T("白色")              }
};

/////////////////////////////////////////////////////////////////////////////
// CColorPopup

CColorPopup::CColorPopup()
{
    Initialise();
}

CColorPopup::CColorPopup(CPoint p, COLORREF crColor, CWnd* pParentWnd,
                           LPCTSTR szDefaultText /* = NULL */,
                           LPCTSTR szCustomText  /* = NULL */)
{
    Initialise();

    m_crColor        = m_crInitialColor = crColor;
    m_pParent        = pParentWnd;
    m_strDefaultText = (szDefaultText)? szDefaultText : _T("");
    m_strCustomText  = (szCustomText)?  szCustomText  : _T("");
	m_crDefaultColor = ::GetSysColor(COLOR_BTNTEXT);

	CColorPopup::Create(p, crColor, pParentWnd, szDefaultText, szCustomText);
}

////////////////////////////////////////////////////////////////////
void CColorPopup::Initialise()
{
    m_nNumColors       = sizeof(m_crColors)/sizeof(ColorTableEntry);
    ASSERT(m_nNumColors <= MAX_COLOURS);
    if (m_nNumColors > MAX_COLOURS)
        m_nNumColors = MAX_COLOURS;

    m_nNumColumns       = 0;
    m_nNumRows          = 0;
    m_nBoxSize          = 18;
    m_nMargin           = ::GetSystemMetrics(SM_CXEDGE);
    m_nCurrentSel       = INVALID_COLOUR;
    m_nChosenColorSel   = INVALID_COLOUR;
    m_pParent           = NULL;
    m_crColor           = m_crInitialColor = RGB(0,0,0);

    // Make sure the colour square is at least 5 x 5;
    if (m_nBoxSize - 2*m_nMargin - 2 < 5) m_nBoxSize = 5 + 2*m_nMargin + 2;

    // Create the font
    NONCLIENTMETRICS ncm;
    ncm.cbSize = sizeof(NONCLIENTMETRICS);
    VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 
								sizeof(NONCLIENTMETRICS), &ncm, 0));
    m_Font.CreateFontIndirect(&(ncm.lfMessageFont));

    // Create the palette
    struct {
        LOGPALETTE    LogPalette;
        PALETTEENTRY  PalEntry[MAX_COLOURS];
    } pal;

    LOGPALETTE* pLogPalette = (LOGPALETTE*) &pal;
    pLogPalette->palVersion    = 0x300;
    pLogPalette->palNumEntries = (WORD) m_nNumColors; 

    for (int i = 0; i < m_nNumColors; i++)
    {
        pLogPalette->palPalEntry[i].peRed   = GetRValue(m_crColors[i].crColor);
        pLogPalette->palPalEntry[i].peGreen = GetGValue(m_crColors[i].crColor);
        pLogPalette->palPalEntry[i].peBlue  = GetBValue(m_crColors[i].crColor);
        pLogPalette->palPalEntry[i].peFlags = 0;
    }

    m_Palette.CreatePalette(pLogPalette);
}

////////////////////////////////////////////////////////////////////
CColorPopup::~CColorPopup()
{
    m_Font.DeleteObject();
    m_Palette.DeleteObject();
}

//////////////////////////////////////////////////////////////////////
BOOL CColorPopup::Create(CPoint p, COLORREF crColor, CWnd* pParentWnd,
                          LPCTSTR szDefaultText,
                          LPCTSTR szCustomText )
{
    ASSERT(pParentWnd && ::IsWindow(pParentWnd->GetSafeHwnd()));
    //ASSERT(pParentWnd->IsKindOf(RUNTIME_CLASS(CColorButton)));

    m_pParent  = pParentWnd;
    m_crColor = m_crInitialColor = crColor;

    // Get the class name and create the window
    CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|
											  CS_VREDRAW, 0,
											  (HBRUSH)GetStockObject(LTGRAY_BRUSH),0);
		
    if (!CWnd::CreateEx(0, szClassName, _T(""), WS_VISIBLE|WS_POPUP, 
			p.x, p.y, 100, 100, // size updated soon
			pParentWnd->GetSafeHwnd(), 0, NULL))
			return FALSE;

    // Store the Custom text
    if (szCustomText != NULL) 
        m_strCustomText = szCustomText;

    // Store the Default Area text
    if (szDefaultText != NULL) 
        m_strDefaultText = szDefaultText;
        
    // Set the window size
    SetWindowSize();

    // Create the tooltips
    CreateToolTips();

    // Find which cell corresponds to the initial color
    FindCellFromColor(crColor);

    // Capture all mouse events for the life of this window
    SetCapture();

    return TRUE;
}

BEGIN_MESSAGE_MAP(CColorPopup, CWnd)
    //{{AFX_MSG_MAP(CColorPopup)
    ON_WM_NCDESTROY()
    ON_WM_LBUTTONUP()
    ON_WM_PAINT()
    ON_WM_MOUSEMOVE()
    ON_WM_KEYDOWN()
    ON_WM_QUERYNEWPALETTE()
    ON_WM_PALETTECHANGED()
	ON_WM_KILLFOCUS()
	ON_WM_ACTIVATEAPP()
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CColorPopup message handlers
// For tooltips
BOOL CColorPopup::PreTranslateMessage(MSG* pMsg) 
{
    m_ToolTip.RelayEvent(pMsg);
    return CWnd::PreTranslateMessage(pMsg);
}

///////////////////////////////////////////////////////////////////
// If an arrow key is pressed, then move the selection
void CColorPopup::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    int row = GetRow(m_nCurrentSel);
    int col = GetColumn(m_nCurrentSel);
    int nSelection = m_nCurrentSel;

    if (nChar == VK_DOWN) 
    {
        if (row == DEFAULT_BOX_VALUE) 
            row = col = 0; 
        else if (row == CUSTOM_BOX_VALUE)
        {
            if (m_strDefaultText.GetLength())
                row = col = DEFAULT_BOX_VALUE;
            else
                row = col = 0;
        }
        else
        {
            row++;
            if (GetIndex(row,col) < 0)
            {
                if (m_strCustomText.GetLength())
                    row = col = CUSTOM_BOX_VALUE;
                else if (m_strDefaultText.GetLength())
                    row = col = DEFAULT_BOX_VALUE;
                else
                    row = col = 0;
            }
        }
        ChangeSelection(GetIndex(row, col));
    }

    if (nChar == VK_UP) 
    {
        if (row == DEFAULT_BOX_VALUE)
        {
            if (m_strCustomText.GetLength())
                row = col = CUSTOM_BOX_VALUE;
            else
           { 
                row = GetRow(m_nNumColors-1); 
                col = GetColumn(m_nNumColors-1); 
            }
        }
        else if (row == CUSTOM_BOX_VALUE)
        { 
            row = GetRow(m_nNumColors-1); 
            col = GetColumn(m_nNumColors-1); 
        }
        else if (row > 0) row--;
        else 
        {
            if (m_strDefaultText.GetLength())
                row = col = DEFAULT_BOX_VALUE;
            else if (m_strCustomText.GetLength())
                row = col = CUSTOM_BOX_VALUE;
            else
            { 
                row = GetRow(m_nNumColors-1); 
                col = GetColumn(m_nNumColors-1); 
            }
        }
        ChangeSelection(GetIndex(row, col));
    }

    if (nChar == VK_RIGHT) 
    {
        if (row == DEFAULT_BOX_VALUE) 
            row = col = 0; 
        else if (row == CUSTOM_BOX_VALUE)
        {
            if (m_strDefaultText.GetLength())
                row = col = DEFAULT_BOX_VALUE;
            else
                row = col = 0;
        }
        else if (col < m_nNumColumns-1) 
            col++;
        else 
        { 
            col = 0; row++;
        }

        if (GetIndex(row,col) == INVALID_COLOUR)
        {
            if (m_strCustomText.GetLength())
                row = col = CUSTOM_BOX_VALUE;
            else if (m_strDefaultText.GetLength())
                row = col = DEFAULT_BOX_VALUE;
            else
                row = col = 0;
        }

        ChangeSelection(GetIndex(row, col));
    }

    if (nChar == VK_LEFT) 
    {
        if (row == DEFAULT_BOX_VALUE)
        {
            if (m_strCustomText.GetLength())
                row = col = CUSTOM_BOX_VALUE;
            else
           { 
                row = GetRow(m_nNumColors-1); 
                col = GetColumn(m_nNumColors-1); 
            }
        }
        else if (row == CUSTOM_BOX_VALUE)
        { 
            row = GetRow(m_nNumColors-1); 
            col = GetColumn(m_nNumColors-1); 
        }
        else if (col > 0) col--;
        else /* col == 0 */
        {
            if (row > 0) { row--; col = m_nNumColumns-1; }
            else 
            {
                if (m_strDefaultText.GetLength())
                    row = col = DEFAULT_BOX_VALUE;
                else if (m_strCustomText.GetLength())
                    row = col = CUSTOM_BOX_VALUE;
                else
                { 
                    row = GetRow(m_nNumColors-1); 
                    col = GetColumn(m_nNumColors-1); 
                }
            }
        }
        ChangeSelection(GetIndex(row, col));
    }

    if (nChar == VK_ESCAPE) 
    {
        m_crColor = m_crInitialColor;
        EndSelection(CPN_SELENDCANCEL);
        return;
    }

    if (nChar == VK_RETURN || nChar == VK_SPACE)
    {
        EndSelection(CPN_SELENDOK);
        return;
    }

    CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

///////////////////////////////////////////////////////////////////
// auto-deletion
void CColorPopup::OnNcDestroy() 
{
    CWnd::OnNcDestroy();
    delete this;
}
/////////////////////////////////////////////////////////////////////
//Paint the Dialog's background
BOOL CColorPopup::OnEraseBkgnd(CDC* pDC) 
{
	CBrush br(GetSysColor(COLOR_3DFACE));
	CRect rc;
	pDC->GetClipBox(rc);
	CBrush* pOldBrush = pDC->SelectObject(&br);
	
	pDC->PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),PATCOPY);

	pDC->SelectObject(pOldBrush);

	return TRUE;
}

/////////////////////////////////////////////////////////////////////
void CColorPopup::OnPaint() 
{
    // device context for painting
	CPaintDC dc(this); 
	
	// Draw the title with my name
	CRect rectName(4, 1, 154, 17);
	dc.SetBkMode(TRANSPARENT);
	DrawName(&dc,rectName);
		
	// Draw the Default Area text
    DrawCell(&dc, DEFAULT_BOX_VALUE);
	
    // Draw colour cells
    for (int i = 0; i < m_nNumColors; i++)
        DrawCell(&dc, i);
    
    // Draw custom text
    DrawCell(&dc, CUSTOM_BOX_VALUE);

    // Draw raised window edge 
    CRect rect;
    GetClientRect(rect);
    dc.DrawEdge(rect, EDGE_RAISED, BF_RECT);
}

/////////////////////////////////////////////////////////////////////
void CColorPopup::OnMouseMove(UINT nFlags, CPoint point) 
{
    int nNewSelection = INVALID_COLOUR;

    // Translate points to be relative raised window edge
    point.x -= m_nMargin;
    point.y -= m_nMargin;

    // First check whether in text box
    if (m_CustomTextRect.PtInRect(point))
        nNewSelection = CUSTOM_BOX_VALUE;
    else if (m_DefaultTextRect.PtInRect(point))
        nNewSelection = DEFAULT_BOX_VALUE;
    else
    {
        // Take into account text box
        if (m_strDefaultText.GetLength()) 
            point.y -= m_DefaultTextRect.Height();  

        // Get the row and column
        nNewSelection = GetIndex((point.y - MAX_BOTTOM) / m_nBoxSize,
			                      (point.x - MAX_OFFSET) / m_nBoxSize);

        // In range? If not, default and exit
        if (nNewSelection < 0 || nNewSelection >= m_nNumColors)
        {
            CWnd::OnMouseMove(nFlags, point);
            return;
        }
    }
	

    // the row and column of the current selection have been found there,  
    // and if the row/col selection has changed? then redraw old and new cells.
    if (nNewSelection != m_nCurrentSel)
        ChangeSelection(nNewSelection);

    CWnd::OnMouseMove(nFlags, point);
}

///////////////////////////////////////////////////////////////////
// End selection on LButtonUp
void CColorPopup::OnLButtonUp(UINT nFlags, CPoint point) 
{    
    CWnd::OnLButtonUp(nFlags, point);

    DWORD pos = GetMessagePos();
    point = CPoint(LOWORD(pos), HIWORD(pos));

    if (m_WindowRect.PtInRect(point))
        EndSelection(CPN_SELENDOK);
    else
        EndSelection(CPN_SELENDCANCEL);
}

/////////////////////////////////////////////////////////////////////////////
// Get the index of clolor cell 
int CColorPopup::GetIndex(int row, int col) const
{ 
    if ((row == CUSTOM_BOX_VALUE || col == CUSTOM_BOX_VALUE) && m_strCustomText.GetLength())
        return CUSTOM_BOX_VALUE;
    else if ((row == DEFAULT_BOX_VALUE || col == DEFAULT_BOX_VALUE) && m_strDefaultText.GetLength())
        return DEFAULT_BOX_VALUE;
    else if (row < 0 || col < 0 || row >= m_nNumRows || col >= m_nNumColumns)
        return INVALID_COLOUR;
    else
    {
        if (row*m_nNumColumns + col >= m_nNumColors)
            return INVALID_COLOUR;
        else
            return row*m_nNumColumns + col;
    }
}

////////////////////////////////////////////////////////////////////////////
// Get the Row number
int CColorPopup::GetRow(int nIndex) const               
{ 
    if (nIndex == CUSTOM_BOX_VALUE && m_strCustomText.GetLength())
        return CUSTOM_BOX_VALUE;
    else if (nIndex == DEFAULT_BOX_VALUE && m_strDefaultText.GetLength())
        return DEFAULT_BOX_VALUE;
    else if (nIndex < 0 || nIndex >= m_nNumColors)
        return INVALID_COLOUR;
    else
        return nIndex / m_nNumColumns; 
}

/////////////////////////////////////////////////////////////////
// Get the Column number
int CColorPopup::GetColumn(int nIndex) const            
{ 
    if (nIndex == CUSTOM_BOX_VALUE && m_strCustomText.GetLength())
        return CUSTOM_BOX_VALUE;
    else if (nIndex == DEFAULT_BOX_VALUE && m_strDefaultText.GetLength())
        return DEFAULT_BOX_VALUE;
    else if (nIndex < 0 || nIndex >= m_nNumColors)
        return INVALID_COLOUR;
    else
        return nIndex % m_nNumColumns; 
}

///////////////////////////////////////////////////////////////////
//
void CColorPopup::FindCellFromColor(COLORREF crColor)
{
    if (crColor == m_crDefaultColor && m_strDefaultText.GetLength())
    {
        m_nChosenColorSel = DEFAULT_BOX_VALUE;
        return;
    }

    for (int i = 0; i < m_nNumColors; i++)
    {
        if (GetColor(i) == crColor)
        {
            m_nChosenColorSel = i;
            return;
        }
    }

    if (m_strCustomText.GetLength())
        m_nChosenColorSel = CUSTOM_BOX_VALUE;
    else
        m_nChosenColorSel = INVALID_COLOUR;
}

///////////////////////////////////////////////////////////////////
// Gets the dimensions of the colour cell given by (row,col)
BOOL CColorPopup::GetCellRect(int nIndex, const LPRECT& rect)
{
    if (nIndex == CUSTOM_BOX_VALUE)
    {
        ::SetRect(rect, 
                  m_CustomTextRect.left,  m_CustomTextRect.top,
                  m_CustomTextRect.right, m_CustomTextRect.bottom);
        return TRUE;
    }
    else if (nIndex == DEFAULT_BOX_VALUE)
    {
        ::SetRect(rect, 
                  m_DefaultTextRect.left,  m_DefaultTextRect.top,
                  m_DefaultTextRect.right, m_DefaultTextRect.bottom);
        return TRUE;
    }

    if (nIndex < 0 || nIndex >= m_nNumColors)
        return FALSE;

    rect->left = MAX_OFFSET + GetColumn(nIndex) * m_nBoxSize + m_nMargin;
    rect->top  = MAX_BOTTOM + GetRow(nIndex) * m_nBoxSize + m_nMargin;

    // Move everything down if we are displaying a default text area
    if (m_strDefaultText.GetLength()) 
        rect->top += (m_nMargin + m_DefaultTextRect.Height());

    rect->right = rect->left + m_nBoxSize;
    rect->bottom = rect->top + m_nBoxSize;

    return TRUE;
}

////////////////////////////////////////////////////////////////
// Works out an appropriate size and position of this window
void CColorPopup::SetWindowSize()
{
    CSize TextSize;

    // If we are showing a custom or default text area, get the font and text size.
    if (m_strCustomText.GetLength() || m_strDefaultText.GetLength())
    {
        CClientDC dc(this);
        CFont* pOldFont = (CFont*) dc.SelectObject(&m_Font);

        // Get the size of the custom text
        TextSize = CSize(0,0);
        if (m_strCustomText.GetLength())
            TextSize = dc.GetTextExtent(m_strCustomText);

        // Get the size of the default text 
        if (m_strDefaultText.GetLength())
        {
            CSize DefaultSize = dc.GetTextExtent(m_strDefaultText);
            if (DefaultSize.cx > TextSize.cx) TextSize.cx = DefaultSize.cx;
            if (DefaultSize.cy > TextSize.cy) TextSize.cy = DefaultSize.cy;
        }

        dc.SelectObject(pOldFont);
        TextSize += CSize(2*m_nMargin,2*m_nMargin);

        // Add even more space to draw the horizontal line
        TextSize.cy += 2*m_nMargin + 2;
    }

    // Get the number of columns and rows
    m_nNumColumns = 8;
    m_nNumRows = m_nNumColors / m_nNumColumns;
    if (m_nNumColors % m_nNumColumns) m_nNumRows++;
	
    // Get the current window position, and set the new size
    CRect rect;
    GetWindowRect(rect);

    m_WindowRect.SetRect(rect.left, rect.top, 
                         rect.left + m_nNumColumns*m_nBoxSize + 2*m_nMargin+ 2* MAX_OFFSET,
                         rect.top  + m_nNumRows*m_nBoxSize + 2*m_nMargin + MAX_BOTTOM );

    // if custom text, then expand window if necessary, and set text width as
    // window width
    if (m_strDefaultText.GetLength()) 
    {
        if (TextSize.cx > m_WindowRect.Width())
            m_WindowRect.right = m_WindowRect.left + TextSize.cx;
        TextSize.cx = m_WindowRect.Width()-2*m_nMargin-20;

        // Work out the text area
        m_DefaultTextRect.SetRect(m_nMargin, m_nMargin, 
                                  m_nMargin+TextSize.cx+2 , 2*m_nMargin+TextSize.cy);
        m_DefaultTextRect.OffsetRect ( 2 * MAX_OFFSET,MAX_BOTTOM);
		m_WindowRect.bottom += m_DefaultTextRect.Height() + 2*m_nMargin;
		
    }
	
    // if custom text, then expand window if necessary, and set text width as
    // window width
    if (m_strCustomText.GetLength()){
        if (TextSize.cx > m_WindowRect.Width())
            m_WindowRect.right = m_WindowRect.left + TextSize.cx;
        TextSize.cx = m_WindowRect.Width()-2*m_nMargin-20;

        // Work out the text area
        m_CustomTextRect.SetRect(m_nMargin, m_WindowRect.Height(), 
                                 m_nMargin+TextSize.cx , 
                                 m_WindowRect.Height()+m_nMargin+TextSize.cy);
        m_CustomTextRect.OffsetRect ( 2 * MAX_OFFSET , 0 );
		m_WindowRect.bottom += m_CustomTextRect.Height() + 2*m_nMargin + MAX_OFFSET;
   }

    // Need to check it'll fit on screen
    CSize ScreenSize(::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN));
    if (m_WindowRect.right > ScreenSize.cx)
        m_WindowRect.OffsetRect(-(m_WindowRect.right - ScreenSize.cx), 0);

    // Too far left?
    if (m_WindowRect.left < 0)
        m_WindowRect.OffsetRect( -m_WindowRect.left, 0);

    // Bottom falling out of screen?
    if (m_WindowRect.bottom > ScreenSize.cy)
    {
        CRect ParentRect;
        m_pParent->GetWindowRect(ParentRect);
        m_WindowRect.OffsetRect(0, -(ParentRect.Height() + m_WindowRect.Height()));
    }

    // Set the window size and position
    MoveWindow(m_WindowRect, TRUE);
}

////////////////////////////////////////////////////////////////
void CColorPopup::CreateToolTips()
{
    // Create the tool tip
    if (!m_ToolTip.Create(this)) return;

    // Add a tool for each cell
    for (int i = 0; i < m_nNumColors; i++)
    {
        CRect rect;
        if (!GetCellRect(i, rect)) continue;
            m_ToolTip.AddTool(this, GetColorName(i), rect, 1);
    }
}

//////////////////////////////////////////////////////////////////
void CColorPopup::ChangeSelection(int nIndex)
{
    CClientDC dc(this);        // device context for drawing

    if (nIndex > m_nNumColors)
        nIndex = CUSTOM_BOX_VALUE; 

    if ((m_nCurrentSel >= 0 && m_nCurrentSel < m_nNumColors) ||
        m_nCurrentSel == CUSTOM_BOX_VALUE || m_nCurrentSel == DEFAULT_BOX_VALUE)
    {
        // Set Current selection as invalid and redraw old selection (this way
        // the old selection will be drawn unselected)
        int OldSel = m_nCurrentSel;
        m_nCurrentSel = INVALID_COLOUR;
        DrawCell(&dc, OldSel);
    }

    // Set the current selection as row/col and draw (it will be drawn selected)
    m_nCurrentSel = nIndex;
    DrawCell(&dc, m_nCurrentSel);

    // Store the current colour
    if (m_nCurrentSel == CUSTOM_BOX_VALUE)
        m_pParent->SendMessage(CPN_SELCHANGE, (WPARAM) m_crInitialColor, 0);
    else if (m_nCurrentSel == DEFAULT_BOX_VALUE)
    {
        m_crColor = m_crDefaultColor;
        m_pParent->SendMessage(CPN_SELCHANGE, (WPARAM) m_crDefaultColor, 0);
    }
    else
    {
        m_crColor = GetColor(m_nCurrentSel);
        m_pParent->SendMessage(CPN_SELCHANGE, (WPARAM) m_crColor, 0);
    }
}

///////////////////////////////////////////////////////////////////
/// Send the end message
void CColorPopup::EndSelection(int nMessage)
{
  

    // If custom text selected, perform a custom colour selection
    if (nMessage != CPN_SELENDCANCEL && m_nCurrentSel == CUSTOM_BOX_VALUE)
    {
        
		CColorDialog dlg;
		
		if (dlg.DoModal() == IDOK)
            m_crColor = dlg.GetColor();
        else
            m_crColor = m_crInitialColor;
		
	 } 

    if (nMessage == CPN_SELENDCANCEL)
        m_crColor = m_crInitialColor;

    m_pParent->SendMessage(nMessage, (WPARAM) m_crColor, 0);
    
	ReleaseCapture();
    DestroyWindow();
}

////////////////////////////////////////////////////////////////
void CColorPopup::DrawCell(CDC* pDC, int nIndex)
{
    CRect rect;
	/////////////////////////////////////
	// For the Custom Text area
    if (m_strCustomText.GetLength() && nIndex == CUSTOM_BOX_VALUE)
    {
        // The extent of the actual text button
        CRect TextButtonRect = m_CustomTextRect;
        TextButtonRect.top += 2*m_nMargin;
		TextButtonRect.DeflateRect(MAX_TEXTRECT,0);

        // Fill background
        pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DFACE));

		
        // Draw horizontal line
        pDC->FillSolidRect(m_CustomTextRect.left+2*m_nMargin, m_CustomTextRect.top,
                           m_CustomTextRect.Width()-4*m_nMargin, 1,
						   ::GetSysColor(COLOR_3DSHADOW));
        
		pDC->FillSolidRect(m_CustomTextRect.left+2*m_nMargin, m_CustomTextRect.top+1,
                           m_CustomTextRect.Width()-4*m_nMargin, 1,
						   ::GetSysColor(COLOR_3DHILIGHT));
		
        TextButtonRect.DeflateRect(1,1);

        // fill background
        if (m_nChosenColorSel == nIndex && m_nCurrentSel != nIndex)
            pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DLIGHT));
        else
            pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DFACE));
		
		// fill Selected background
		if (m_nChosenColorSel == nIndex)
			pDC->FillSolidRect(TextButtonRect, RGB(0xE6,0xE6,0xE6));
		
		// Draw button
        if (m_nCurrentSel == nIndex){
				if (m_nChosenColorSel == nIndex){
					pDC->Draw3dRect(TextButtonRect, ::GetSysColor(COLOR_BTNSHADOW),
									::GetSysColor(COLOR_BTNHILIGHT));
					rect = TextButtonRect;
					rect.DeflateRect (1,1);
					pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
				}	
				else
 					pDC->Draw3dRect(TextButtonRect, ::GetSysColor(COLOR_BTNHILIGHT) ,
									::GetSysColor(COLOR_BTNSHADOW));
			}
		else if (m_nChosenColorSel == nIndex)
            pDC->Draw3dRect(TextButtonRect, ::GetSysColor(COLOR_BTNSHADOW), 
							::GetSysColor(COLOR_BTNHILIGHT));
		
		
		// Draw custom text
        CFont *pOldFont = (CFont*) pDC->SelectObject(&m_Font);
        pDC->SetBkMode(TRANSPARENT);
        pDC->DrawText(m_strCustomText, TextButtonRect, DT_CENTER |
					  DT_VCENTER | DT_SINGLELINE);
        pDC->SelectObject(pOldFont);

        return;
    }        
	//////////////////////////////////////////
    // For the Default Text area
    if (nIndex == DEFAULT_BOX_VALUE)
    {
        // Fill background
        pDC->FillSolidRect(m_DefaultTextRect, ::GetSysColor(COLOR_3DFACE));

        // The extent of the actual text button
        CRect TextButtonRect = m_DefaultTextRect;
        TextButtonRect.DeflateRect(1,1);
		TextButtonRect.DeflateRect(MAX_TEXTRECT,0);
		

        // fill background
        if (m_nChosenColorSel == nIndex && m_nCurrentSel != nIndex)
            pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DLIGHT));
        else
            pDC->FillSolidRect(TextButtonRect, ::GetSysColor(COLOR_3DFACE));
				
		// fill Selected background
		if (m_nChosenColorSel == nIndex)
			pDC->FillSolidRect(TextButtonRect, RGB(0xE6,0xE6,0xE6));
	
        // Draw the line around text
        CRect LineRect = TextButtonRect;
        LineRect.DeflateRect(2*m_nMargin,2*m_nMargin);
        CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
        CPen* pOldPen = pDC->SelectObject(&pen);
        pDC->SelectStockObject(NULL_BRUSH);
        pDC->Rectangle(LineRect);
        pDC->SelectObject(pOldPen);
		
	    // Draw button
        if (m_nCurrentSel == nIndex){
				if (m_nChosenColorSel == nIndex){
					pDC->Draw3dRect(TextButtonRect, ::GetSysColor(COLOR_BTNSHADOW), 
									::GetSysColor(COLOR_BTNHILIGHT));
					//CRect rect;
					rect = TextButtonRect;
					rect.DeflateRect (1,1);
					pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
					pOldPen = pDC->SelectObject(&pen);
					pDC->SelectStockObject(NULL_BRUSH);
					pDC->Rectangle(LineRect);
					pDC->SelectObject(pOldPen);
				}
				else
 					pDC->Draw3dRect(TextButtonRect, ::GetSysColor(COLOR_BTNHILIGHT) ,
									::GetSysColor(COLOR_BTNSHADOW));
			}
		else if (m_nChosenColorSel == nIndex)
            pDC->Draw3dRect(TextButtonRect, ::GetSysColor(COLOR_BTNSHADOW), 
							::GetSysColor(COLOR_BTNHILIGHT));
		
        // Draw the default demo color cell
		CBrush brush(::GetSysColor(COLOR_BTNTEXT));
		CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
		CPen   penDefault;
		penDefault.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));

		CRect DefRect ;
		DefRect = LineRect;
		DefRect.DeflateRect(m_nMargin,m_nMargin);
		CRect DefaltRect(DefRect.left+5 ,DefRect.top ,DefRect.left+15 ,DefRect.top+10);
		
        CBrush* pOldBrushDefault = (CBrush*) pDC->SelectObject(&brush);
        CPen*   pOldPenDefault   = (CPen*)   pDC->SelectObject(&pen);
	    pDC->Rectangle(DefaltRect);

					
		// Draw custom text
        CFont *pOldFont = (CFont*) pDC->SelectObject(&m_Font);
        pDC->SetBkMode(TRANSPARENT);
        pDC->DrawText(m_strDefaultText, TextButtonRect, DT_CENTER |
						DT_VCENTER | DT_SINGLELINE);
        pDC->SelectObject(pOldFont);
		
		return;
    }        
	
	/////////////////////////////////////////////
	//// For the color cells area
    if (!GetCellRect(nIndex, rect)) return;

    // Select and realize the palette
    CPalette* pOldPalette;
    if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
    {
        pOldPalette = pDC->SelectPalette(&m_Palette, FALSE);
        pDC->RealizePalette();
    }


    // fill background
    if (m_nChosenColorSel == nIndex && m_nCurrentSel != nIndex)
        pDC->FillSolidRect(rect, RGB(0xDC,0xDC,0xDC));
    else
        pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
	
	if (m_nChosenColorSel == nIndex){
		pDC->FillSolidRect(rect, RGB(0xE6,0xE6,0xE6));
		pDC->Draw3dRect(rect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIGHT));
	}	
	
	
	// Draw button
    if (m_nCurrentSel == nIndex){
		if (m_nChosenColorSel == nIndex){
			pDC->Draw3dRect(rect, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHILIGHT));
			CRect rectbtn;
			rectbtn = rect;
			rectbtn.DeflateRect (1,1);
			pDC->FillSolidRect(rectbtn, ::GetSysColor(COLOR_3DFACE));
		}	
		else
 			pDC->Draw3dRect(rect, ::GetSysColor(COLOR_BTNHILIGHT) ,::GetSysColor(COLOR_BTNSHADOW));
	}
	

    CBrush brush(PALETTERGB(GetRValue(GetColor(nIndex)), 
                            GetGValue(GetColor(nIndex)), 
                            GetBValue(GetColor(nIndex)) ));
    CPen   pen;
    pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));

    CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
    CPen*   pOldPen   = (CPen*)   pDC->SelectObject(&pen);

    // Draw the cell colour
    rect.DeflateRect(m_nMargin+1, m_nMargin+1);
    pDC->Rectangle(rect);

    // restore DC and cleanup
    pDC->SelectObject(pOldBrush);
    pDC->SelectObject(pOldPen);
    brush.DeleteObject();
    pen.DeleteObject();

    if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
        pDC->SelectPalette(pOldPalette, FALSE);
}

///////////////////////////////////////////////////////////////
BOOL CColorPopup::OnQueryNewPalette() 
{
    Invalidate();    
    return CWnd::OnQueryNewPalette();
}

//////////////////////////////////////////////////////////////////
void CColorPopup::OnPaletteChanged(CWnd* pFocusWnd) 
{
    CWnd::OnPaletteChanged(pFocusWnd);

    if (pFocusWnd->GetSafeHwnd() != GetSafeHwnd())
        Invalidate();
}

///////////////////////////////////////////////////////////////////
void CColorPopup::OnKillFocus(CWnd* pNewWnd) 
{
	CWnd::OnKillFocus(pNewWnd);
	
	//m_pParent->SendMessage(CPN_SELENDCANCEL, (WPARAM) m_crColor, 0);
	//EndSelection(CPN_SELENDCANCEL);
    
	//ReleaseCapture();
    //DestroyWindow(); 
}

/////////////////////////////////////////////////////////////////////
// KillFocus 
void CColorPopup::OnActivateApp(BOOL bActive, HTASK hTask) 
{
	CWnd::OnActivateApp(bActive, hTask);

	// If Deactivating App, cancel this selection
	if (!bActive)
		 EndSelection(CPN_SELENDCANCEL);
}

void CColorPopup::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	//SendMessage(WM_SYSCOMMAND, 0xF012);

	CWnd::OnLButtonDown(nFlags, point);
	PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y));

	CWnd::OnLButtonDown(nFlags, point);
}

///////////////////////////////////////////////
void CColorPopup::DrawName (CDC *pDC,CRect rectName)
{
	pDC->DrawText ("选择颜色",rectName, DT_CENTER |
					  DT_VCENTER | DT_SINGLELINE);
}